using System;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Security;

namespace SocketTool.Messengers
{
    public class STWeakReference : ISerializable
    {
         internal IntPtr m_handle;

        public virtual bool IsAlive
        {
            [MethodImpl(MethodImplOptions.InternalCall)]
            [SecuritySafeCritical]
            get;
        }

        public virtual bool TrackResurrection
        {
            get
            {
                return IsTrackResurrection();
            }
        }

        public virtual object Target
        {
            [MethodImpl(MethodImplOptions.InternalCall)]
            [SecuritySafeCritical]
            get;
            [MethodImpl(MethodImplOptions.InternalCall)]
            [SecuritySafeCritical]
            set;
        }

        public STWeakReference(object target)
            : this(target, trackResurrection: false)
        {
        }

        public STWeakReference(object target, bool trackResurrection)
        {
            Create(target, trackResurrection);
        }

        protected STWeakReference(SerializationInfo info, StreamingContext context)
        {
            if (info == null)
            {
                throw new ArgumentNullException("info");
            }

            object value = info.GetValue("TrackedObject", typeof(object));
            bool boolean = info.GetBoolean("TrackResurrection");
            Create(value, boolean);
        }

        [MethodImpl(MethodImplOptions.InternalCall)]
        [SecuritySafeCritical]
        extern ~STWeakReference();

        [SecurityCritical]
        public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            if (info == null)
            {
                throw new ArgumentNullException("info");
            }

            info.AddValue("TrackedObject", Target, typeof(object));
            info.AddValue("TrackResurrection", IsTrackResurrection());
        }

        [MethodImpl(MethodImplOptions.InternalCall)]
        [SecuritySafeCritical]
        private extern void Create(object target, bool trackResurrection);

        [MethodImpl(MethodImplOptions.InternalCall)]
        [SecuritySafeCritical]
        private extern bool IsTrackResurrection();
    }
}